using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;
using FU.Capstones.IMS.Web.Common;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.DataContracts;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.EventArgs;
using FU.Capstones.IMS.Web.Silverlight.Models;
using FU.Capstones.IMS.Web.Silverlight.Popups;
using Microsoft.Practices.Prism.Commands;
using Navigation.Silverlight;
using System.Linq;

namespace FU.Capstones.IMS.Web.Silverlight.ViewModels
{
    public class EmployeeListViewModel : ViewModelBase
    {
        public EmployeeListViewModel()
        {
            Model = new EmployeeListModel();
            ((EmployeeListModel)Model).GetEmployeeCollectionCompleted += DoGetEmployeeCollectionCompleted;
            ((EmployeeListModel)Model).SearhEmployeeCompleted += DoSearhEmployeeCompleted;
            ((EmployeeListModel)Model).DeleteEmployeeCompleted += DoDeleteEmployeeCompleted;
            ((EmployeeListModel)Model).UndoDeleteEmployeeCompleted += UndoDeleteEmployeeCompleted;
            ((EmployeeListModel)Model).GetSingleEmployeeCompleted += DoGetSingleEmployeeCompleted;
            ((EmployeeListModel)Model).GetRoleCollectionCommpleted += DoGetRoleCollectionCommpleted;
            ((EmployeeListModel)Model).GetEmploymentTypeCollectionCompleted += GetEmploymentTypeCollectionCompleted; 
            ServiceCallCounter = 0;
            ServiceCallCounter += ((EmployeeListModel)Model).GetRoleCollectionAsync();
            ServiceCallCounter += ((EmployeeListModel)Model).GetEmploymentTypeCollectionAsync();
            ServiceCallCounter += ((EmployeeListModel)Model).GetEmployeeCollectionAsync(IsShowAll);

            EmployeeCriteria = new EmployeeCriteria();

            Message = WebConstants.LoadingMessage;

        }

        #region Do Completed Methods

        void GetEmploymentTypeCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<EmploymentType> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    EmploymentTypeCollection = e.Result.Data;
                    EmployeeCriteria.EmploymentType = new EmploymentType()
                                                          {
                                                              EmploymentTypeID = 0,
                                                              EmploymentTypeName = "Tất cả"
                                                          };
                    EmploymentTypeCollection.Insert(0, EmployeeCriteria.EmploymentType);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetRoleCollectionCommpleted(object sender, CollectionFeedbackCompletedEventArgs<Role> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    RoleCollection = e.Result.Data;
                    EmployeeCriteria.Role = new Role() {RoleID = 0, RoleName = "Tất cả"};
                    RoleCollection.Insert(0, EmployeeCriteria.Role);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetSingleEmployeeCompleted(object sender, SingleFeedbackCompletedEventArgs<Employee> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoDeleteEmployeeCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    //Employee cEmployee =
                    //    EmployeeCollection.Cast<Employee>().FirstOrDefault(ee => ee.EmployeeID == currentEmployeeID);
                    //EmployeeCollection.Remove(cEmployee);
                    ServiceCallCounter += ((EmployeeListModel)Model).GetEmployeeCollectionAsync(IsShowAll);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void UndoDeleteEmployeeCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    NavigationManager.NavigateTo(WebConstants.NavigationPages.EmployeeDetail, new NavigationData() { NavigationUri = WebConstants.NavigationPages.EmployeeList, Data = currentEmployeeID });
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoSearhEmployeeCompleted(object sender, CollectionFeedbackCompletedEventArgs<Employee> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    MessageVisibility = Visibility.Collapsed;

                    var temp = e.Result.Data.FirstOrDefault(x => x.EmployeeID == CurrentUser.EmployeeID);
                    if (temp!=null)
                        e.Result.Data.Remove(temp);

                    EmployeeCollection = new PagedCollectionView(e.Result.Data);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetEmployeeCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Employee> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    var temp = e.Result.Data.FirstOrDefault(x => x.EmployeeID == CurrentUser.EmployeeID);
                    if (temp != null)
                        e.Result.Data.Remove(temp);

                    EmployeeCollection = new PagedCollectionView(e.Result.Data);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        #endregion

        #region Commands

        #region ViewCommand

        private DelegateCommand<Employee> viewCommand;
        public DelegateCommand<Employee> ViewCommand
        {
            get
            {
                if (viewCommand == null)
                {
                    viewCommand = new DelegateCommand<Employee>(DoViewCommand);
                }
                return viewCommand;
            } 
        }

        private void DoViewCommand(Employee obj)
        {
            ServiceCallCounter += ((EmployeeListModel)Model).GetSingleEmployeeAsync(obj.EmployeeID);
        }

        #endregion

        #region ShowAllCommand

        private DelegateCommand<object> showAllCommand;
        public DelegateCommand<object> ShowAllCommand
        {
            get
            {
                if (showAllCommand == null)
                {
                    showAllCommand = new DelegateCommand<object>(DoShowAllCommand);
                }
                return showAllCommand;
            }
        }

        private void DoShowAllCommand(object obj)
        {
            ServiceCallCounter +=
                ((EmployeeListModel)Model).GetEmployeeCollectionAsync(IsShowAll);
        }

        #endregion

        #region EditCommand

        private DelegateCommand<int?> editCommand;
        public DelegateCommand<int?> EditCommand
        {
            get
            {
                if (editCommand == null)
                {
                    editCommand = new DelegateCommand<int?>(DoEditCommand);
                }
                return editCommand;
            }
        }

        private void DoEditCommand(int? obj)
        {
            if (obj.HasValue)
            {
                currentEmployeeID = obj.Value;
                var temp = EmployeeCollection.Cast<Employee>().FirstOrDefault(x => x.EmployeeID == currentEmployeeID);
                if (temp.IsDelete)
                {
                    var popup = new UndoDeleteConfirmationPopup();
                    popup.Show();
                    popup.Closed += (sender, e) =>
                                        {
                                            if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                                            {
                                                ServiceCallCounter += ((EmployeeListModel) Model).UndoDeleteEmployeeAsync(currentEmployeeID);
                                            }
                                        };
                }
                else
                {
                    NavigationManager.NavigateTo(WebConstants.NavigationPages.EmployeeDetail, new NavigationData() {NavigationUri = WebConstants.NavigationPages.EmployeeList, Data = currentEmployeeID});
                }
            }
        }

        #endregion

        #region DeleteCommand

        private DelegateCommand<int?> deleteCommand;
        public DelegateCommand<int?> DeleteCommand
        {
            get
            {
                if (deleteCommand == null)
                {
                    deleteCommand = new DelegateCommand<int?>(DoDeleteCommand);
                }
                return deleteCommand;
            }
        }

        private void DoDeleteCommand(int? obj)
        {
            if (obj.HasValue)
            {
                DeleteConfirmationPopup popup = new DeleteConfirmationPopup();
                popup.Show();
                popup.Closed += (sender, e) =>
                {
                    if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                    {
                        ServiceCallCounter +=
                            ((EmployeeListModel)Model).DeleteEmployeeAsync(obj.Value);
                        currentEmployeeID = obj.Value;
                        Message = "Deleting the selected employee!";
                    }
                };
            }
        }

        #endregion

        #region CreateCommand

        private DelegateCommand<Employee> createCommand;
        public DelegateCommand<Employee> CreateCommand
        {
            get
            {
                if (createCommand == null)
                {
                    createCommand = new DelegateCommand<Employee>(DoCreateCommand);
                }
                return createCommand;
            }
        }

        private void DoCreateCommand(object obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.EmployeeDetail, new NavigationData() { NavigationUri = WebConstants.NavigationPages.EmployeeList, Data = null });
        }

        #endregion

        #region SearchCommand

        private DelegateCommand<object> searchCommand;
        public DelegateCommand<object> SearchCommand
        {
            get
            {
                if (searchCommand == null)
                {
                    searchCommand = new DelegateCommand<object>(DoSearchCommand);
                }
                return searchCommand;
            }
        }

        private void DoSearchCommand(object obj)
        {
            if (EmployeeCriteria.SelectedRole != null && EmployeeCriteria.SelectedRole.RoleID != 0)
            {
                if (EmployeeCriteria.RoleIDCollection == null)
                {
                    EmployeeCriteria.RoleIDCollection = new ObservableCollection<int>();
                }
                else
                {
                    EmployeeCriteria.RoleIDCollection.Clear();
                }
                EmployeeCriteria.RoleIDCollection.Add(EmployeeCriteria.SelectedRole.RoleID);
            }
            else
            {
                EmployeeCriteria.RoleIDCollection = new ObservableCollection<int>();
            }

            ServiceCallCounter += ((EmployeeListModel)Model).SearchEmployeeAsync(EmployeeCriteria);
            Message = WebConstants.SearchingMessage;
        }

        #endregion

        #endregion

        #region Binding Properties

        private PagedCollectionView employeeCollection;
        public PagedCollectionView EmployeeCollection
        {
            get { return employeeCollection; }
            set
            {
                if (!ReferenceEquals(employeeCollection, value))
                {
                    employeeCollection = value;
                    RaisePropertyChanged(() => EmployeeCollection);
                }
            }
        }

        private EmployeeCriteria employeeCriteria;
        public EmployeeCriteria EmployeeCriteria
        {
            get { return employeeCriteria; }
            set
            {
                if (!ReferenceEquals(employeeCriteria, value))
                {
                    employeeCriteria = value;
                    RaisePropertyChanged(() => EmployeeCriteria);
                }
            }
        }

        private ObservableCollection<Role> roleCollection;
        public ObservableCollection<Role> RoleCollection
        {
            get { return roleCollection; }
            set
            {
                if(!ReferenceEquals(roleCollection, value))
                {
                    roleCollection = value;
                    RaisePropertyChanged(() => RoleCollection);
                }
            }
        }

        private ObservableCollection<EmploymentType> eTypeCollection;
        public ObservableCollection<EmploymentType> EmploymentTypeCollection
        {
            get { return eTypeCollection; }
            set
            {
                if (!ReferenceEquals(eTypeCollection, value))
                {
                    eTypeCollection = value;
                    RaisePropertyChanged(() => EmploymentTypeCollection);
                }
            }
        }

        #endregion

        #region Fields

        private int currentEmployeeID;

        #endregion
        
        #region Implementation of INavigationAware

        public override void OnNavigate(object extraData)
        {
            //((EmployeeListModel) model).GetEmployeeCollectionAsync();
        }

        public override void OnLeave()
        {
            //throw new NotImplementedException();
        }

        #endregion

        protected override void HandleLoadingCompleted()
        {
            if (ServiceCallCounter == 0)
            {
                CanEditOrAdd = CurrentUser.CanEditEmployee;
                CanAdd = CurrentUser.CanAddEmployee;
            }
        }
    }
}
